package vn.co.thn.android.serviceconnect.parse;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class BaseParse {
	@SuppressWarnings("unchecked")
	public static <T> T ParserJsonToObject(JSONObject jsonObject, Class<T> clazz) throws Exception {
		List<Field> fields = new ArrayList<Field>();
		fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
		Object object = clazz.getConstructor().newInstance();
		for (Field field : fields) {
			field.setAccessible(true);
			try {
				Object value = jsonObject.get(field.getName());
				if (value != null) {
					if (value instanceof JSONArray) {
						if (List.class.isAssignableFrom(field.getType())) {
							ParameterizedType pType = (ParameterizedType) field.getGenericType();
							Type castType = pType.getActualTypeArguments()[0];
							field.set(object, parserJsonArrayToArrayList((JSONArray) value, castType));
						} else {
							field.set(object, value.toString());
						}
					} else {
						if (value instanceof JSONObject) {
							if (Object.class.isAssignableFrom(field.getType())) {
								field.set(object, ParserJsonToObject((JSONObject) value, field.getType()));
							} else {
								field.set(object, value.toString());
							}

						} else {
							field.set(object, value.getClass().cast(value));
						}
					}
				} else {
					field.set(object, null);
				}
			} catch (JSONException e) {
			}
		}
		return (T) object;
	}

	//
	public static <T> T ParserJsonToObject(String jsonObject, Class<T> clazz) throws Exception {
		return ParserJsonToObject(new JSONObject(jsonObject), clazz);
	}

	@SuppressWarnings("unchecked")
	public static <T extends Object> ArrayList<T> parserJsonArrayToArrayList(JSONArray ja, Type clazzType) throws Exception {

		Class<?> clazz = (Class<?>) clazzType;
		ArrayList<T> result = new ArrayList<T>();

		if (String.class.isAssignableFrom(clazz)) {
			for (int i = 0; i < ja.length(); i++)
				result.add((T) ja.get(i));
		} else {
			if (JSONArray.class.isAssignableFrom(clazz)) {
				for (int i = 0; i < ja.length(); i++)
					result.add((T) ja.get(i));
			} else {
				for (int i = 0; i < ja.length(); i++) {
					Object value = ja.get(i);
					if (value instanceof JSONArray) {
						return parserJsonArrayToArrayList(ja.getJSONArray(i), clazz);
					} else {
						result.add((T) ParserJsonToObject(ja.getJSONObject(i), clazz));
					}
				}
			}
		}
		return result;

	}
}
